package scheduler;

import java.io.*;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import java.text.DateFormat;
import java.util.Date;

import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;

import DB_Manage.*;



public class Main {
	static ArrayList<ScheduledItem> schedule = new ArrayList<ScheduledItem>();
	static LinkedList<User> listOfUsers = new LinkedList<User>();

	// Define a static logger variable so that it references the
	// Logger instance named "main".
	static Logger logger = Logger.getLogger(Main.class);

	DatabaseManager dbm;


	private static int getNoOfJobs() {
		// stub - will be handled by persistence layer
		return 2;
	}



	private static void loadScheduler(boolean today) throws ParseException {
		DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Timer timer = new Timer();

		// For each user, add all of his jobs
		Date nrt = null;
		int delay = 5; // in seconds
		ListIterator<User> itrUsers = listOfUsers.listIterator();
		while(itrUsers.hasNext())
		{
			User usr = (User)itrUsers.next(); 
			ListIterator<Job> itrJobs = usr.jobs.listIterator();
			while(itrJobs.hasNext())
			{
				Job aJob = (Job)itrJobs.next(); 
//				final ScheduledItem scheduledItem = new ScheduledItem();
//				scheduledItem.add(usr.userId, aJob.billingSiteRef, aJob.lastRunDate, aJob.lastStatementDate, aJob.lastStatementTotal);
				final ScheduledItem scheduledItem = new ScheduledItem(usr.userId, aJob.billingSiteRef, aJob.lastRunDate, aJob.lastStatementDate, aJob.lastStatementTotal);
				// Set next run time to shortly
				nrt = soon(delay);
				delay += 5;
				scheduledItem.setNextScheduledRun(nrt);
				schedule.add(scheduledItem);

				timer.schedule(
						new TimerTask() { public void run() { // Task here ... 
							System.out.println("Executing task");
							scheduledItem.executeTask();
							System.out.println("Task completed");
							System.out.println("==============\n\n");
						}
						}, 
						nrt
				);

			}
		}

	}
	/**** Cal to Johan's code
	private void loadScheduler() throws ParseException, SQLException {
		schedule = dbm.retrScheduleItems();
	}

	 */        
	private void loadScheduler() throws ParseException {
		// For each user, add all of his jobs
		ListIterator<User> itrUsers = listOfUsers.listIterator();
		while(itrUsers.hasNext())
		{
			User usr = (User)itrUsers.next(); 
			ListIterator<Job> itrJobs = usr.jobs.listIterator();
			while(itrJobs.hasNext())
			{
				Job aJob = (Job)itrJobs.next(); 
				ScheduledItem scheduledItem = new ScheduledItem(usr.userId, aJob.billingSiteRef, aJob.lastRunDate, aJob.lastStatementDate, aJob.lastStatementTotal);
				schedule.add(scheduledItem);
			}
		}

	}

	public static void loadUsers() throws ParseException {
		int noOfUsersToLoad;
		User user;

		noOfUsersToLoad = getNoOfJobs();
		user = new User();
		user.buildUser("Oweson");
		listOfUsers.add(user);

		user = new User();
		user.buildUser("John");
		listOfUsers.add(user);
	}

	public void printSchedule() {
		System.out.println("Their are " + schedule.size() + " items in the schedule.");

		System.out.println("\n\nIterating through schedule using LinkedList iterator");
		ListIterator<ScheduledItem> itr = schedule.listIterator();
		while(itr.hasNext())
		{
			ScheduledItem si = (ScheduledItem)itr.next(); 
			si.print(true);
		}
	}


	private static void printScheduledTimes() {
		logger.debug("Their are " + schedule.size() + " items in the schedule.");

		logger.debug("\n\nIterating through schedule using LinkedList iterator");
		ListIterator<ScheduledItem> itr = schedule.listIterator();
		while(itr.hasNext())
		{
			ScheduledItem si = (ScheduledItem)itr.next(); 
			si.printScheduledTime();
		}

	}

	// the delay is in seconds
	private static Date soon(int delay) {
		int newHours = (int)(delay / 3600);
		int newMinutes = (int)(delay/60) % 60;
		int newSeconds = delay % 60;

		Calendar cal = Calendar.getInstance();
		cal.getTime();
		cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + newHours);
		cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + newMinutes);
		cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + newSeconds);

		return cal.getTime();
	}

	public static Date tomorrow() {
		Calendar cal = Calendar.getInstance();
		cal.getTime();
		cal.add(Calendar.DATE, 1);
		return cal.getTime();
	}
	public static Date yesterday() {
		Calendar cal = Calendar.getInstance();
		cal.getTime();
		cal.add(Calendar.DATE, -1);
		return cal.getTime();
	}


	/**
	 * @param args
	 * @throws ParseException 
	 */
	public static void main(final String[] args) throws ParseException, IOException, ClassNotFoundException, SQLException {

		BasicConfigurator.configure();
		//PropertyConfigurator.configure("/home/oweson/workspace/Ass2/audit_trail/log4j.cfg");
		//PropertyConfigurator.configure("");
		logger.info("Entering application.");

		//                dbm = new DatabaseManager();

		// load the Users from the persistent store.
		loadUsers();
		logger.debug("Their are " + listOfUsers.size() + " users in the system.");

		logger.debug("\n\nIterating through schedule using LinkedList iterator");
		ListIterator itr = schedule.listIterator();
		while(itr.hasNext())
		{
			User usr = (User)itr.next(); 
			usr.print();    
		}


		for (int i=0;i<schedule.size();i++) {
//			DB_Manage.User usr = dbm.retrUser(schedule.get(i).getUserID());
			User usr = new User();
			usr = usr.retrUser(schedule.get(i).getUserId());
		}

		//DatabaseManager dbm = new DatabaseManager();
		// Create the schedule from the jobs of the users.
		loadScheduler(true); // override next run time to soon

		/* Calculate the next run dates for all items in the schedule.
                bm.retrUser( wiyh the userID rom the scheduked item);
        	BillingSite billingSite = new BillingSite();
                dbm.retrBillingSite( with the billingSiteRef from the scheduled item);
		 * calculate the next run date for the item
		 */

		printScheduledTimes();

		logger.debug("Scheduler completed\n\n");
		logger.info("Exiting application.");


	}



}
